using UnityEngine;

namespace Locomotion
{
    public class JumpTrace : MonoBehaviour
    {
        [SerializeField] private Transform startTrans;
        [SerializeField] private Vector2 direction;
        [SerializeField] private float force;

        public Vector2 Velocity => force * direction;

        private bool _isDotPrepared;

        private void OnValidate()
        {
            UpdateDots(startTrans.position, Velocity);
        }

        public void SetDirection(Vector2 targetDirection)
        {
            direction = targetDirection.normalized;
            UpdateDots(startTrans.position, Velocity);
        }
        
        /// <summary>
        /// 预测点的数量
        /// </summary>
        [SerializeField] private int m_dotsNum = 20;
        /// <summary>
        /// 点物体的父节点
        /// </summary>
        [SerializeField] private GameObject m_dotsParent;
        /// <summary>
        /// 点预设
        /// </summary>
        [SerializeField] private GameObject m_dotsPrefab;
        /// <summary>
        /// 点间距
        /// </summary>
        [SerializeField] private float m_dotSpacing = 0.01f;
        /// <summary>
        /// 点的最小缩放
        /// </summary>
        [SerializeField] [Range(0.01f, 1f)] private float m_dotMinScale = 0.1f;
        /// <summary>
        /// 点的最大缩放
        /// </summary>
        [SerializeField] [Range(0.01f, 1f)] private float m_dotMaxScale = 1f;


        private Transform[] m_dotsList;
        private Vector2 m_pos;
        private float m_timeStamp;

        private void Start()
        {
            Hide();
            PrepareDots();
            // Show();
            UpdateDots(startTrans.position, Velocity);
        }

        /// <summary>
        /// 准备轨迹点
        /// </summary>
        private void PrepareDots()
        {
            m_dotsList = new Transform[m_dotsNum];
            m_dotsPrefab.transform.localScale = Vector3.one * m_dotMaxScale;
            float scale = m_dotMaxScale;
            float scaleFactor = scale / m_dotsNum;

            for (int i = 0; i < m_dotsNum; ++i)
            {
                var dot = Instantiate(m_dotsPrefab).transform;
                dot.parent = m_dotsParent.transform;
                dot.localScale = Vector3.one * scale;
                if (scale > m_dotMinScale)
                    scale -= scaleFactor;
                m_dotsList[i] = dot;
            }

            _isDotPrepared = true;
        }

        /// <summary>
        /// 更新点坐标
        /// </summary>
        /// <param name="birdPos">鸟的坐标</param>
        /// <param name="pushSpeed">初始速度向量</param>
        public void UpdateDots(Vector2 birdPos, Vector2 pushSpeed)
        {
            if (!_isDotPrepared)
            {
                return;
            }
            
            // Debug.Log($"update dots: {birdPos}, {pushSpeed}");
            m_timeStamp = m_dotSpacing;
            
            for (int i = 0; i < m_dotsNum; ++i)
            {
                m_pos.x = birdPos.x + pushSpeed.x * m_timeStamp;
                m_pos.y = (birdPos.y + pushSpeed.y * m_timeStamp) - 0.5f * Physics2D.gravity.magnitude * m_timeStamp * m_timeStamp;
                m_dotsList[i].position = m_pos;
                m_timeStamp += m_dotSpacing;
            }
        }

        /// <summary>
        /// 显示预测轨迹
        /// </summary>
        public void Show()
        {
            m_dotsParent.SetActive(true);
        }

        /// <summary>
        /// 隐藏预测轨迹
        /// </summary>
        public void Hide()
        {
            m_dotsParent.SetActive(false);
        }
    }
}